package cn.dzhang.spring.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotBlank;

@Entity
@Table(name = "users")
@XmlRootElement
public class User implements Serializable {

	private static final long serialVersionUID = -210122606804000568L;
	@Id
	@GenericGenerator(name = "uuid", strategy = "org.hibernate.id.UUIDGenerator")
	@GeneratedValue(generator = "uuid")
	private String id;
	@Column(nullable = false, length = 50, unique = true)
	@Size(max = 50, min = 3)
	@Pattern(regexp = "^\\D[!@#$%^&*\\w]{2,}$")
	private String username;
	@Column(nullable = false, length = 50)
	@Size(max = 50, min = 3)
	@NotBlank
	private String name;
	@Column(nullable = false, length = 50)
	@Size(max = 50, min = 6)
	@NotBlank
	private String password;
	@Email
	@NotBlank
	@Column(length = 50, nullable = false)
	private String email;
	@NotBlank
	@Pattern(regexp = "^((\\+86)|(86))?1\\d{10}$")
	@Column(length = 15, nullable = false)
	private String telephone;
	private boolean online;
	private boolean expired;
	private boolean locked;
	@Column
	@Temporal(TemporalType.TIMESTAMP)
	private Calendar updatedAt = Calendar.getInstance();
	@Column(updatable = false)
	@Temporal(TemporalType.TIMESTAMP)
	private Calendar createdAt = Calendar.getInstance();

	@ManyToMany(fetch = FetchType.EAGER)
	@JoinTable(name = "users_authorities", joinColumns = @JoinColumn(name = "user_id", updatable = true), inverseJoinColumns = @JoinColumn(name = "authority_id", updatable = true))
	@NotNull
	private List<Authority> authorities = new ArrayList<Authority>();

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getTelephone() {
		return telephone;
	}

	public void setTelephone(String telephone) {
		this.telephone = telephone;
	}

	public boolean isOnline() {
		return online;
	}

	public boolean isExpired() {
		return expired;
	}

	public void setExpired(boolean expired) {
		this.expired = expired;
	}

	public boolean isLocked() {
		return locked;
	}

	public void setLocked(boolean locked) {
		this.locked = locked;
	}

	public Calendar getUpdatedAt() {
		return updatedAt;
	}

	public void setUpdatedAt(Calendar updatedAt) {
		this.updatedAt = updatedAt;
	}

	public Calendar getCreatedAt() {
		return createdAt;
	}

	public void setCreatedAt(Calendar createdAt) {
		this.createdAt = createdAt;
	}

	public void setOnline(boolean online) {
		this.online = online;
	}

	public List<Authority> getAuthorities() {
		return authorities;
	}

	public void setAuthorities(List<Authority> authorities) {
		this.authorities = authorities;
	}

	public boolean isCredentialsExpired() {
		updatedAt.add(Calendar.WEEK_OF_MONTH, 1);
		boolean credentialsExpired = Calendar.getInstance().before(updatedAt);
		updatedAt.roll(Calendar.WEEK_OF_MONTH, true);
		credentialsExpired = false;
		return credentialsExpired;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", name=" + name
				+ ", password=" + password + ", email=" + email
				+ ", telephone=" + telephone + ", online=" + online
				+ ", authorities=" + authorities + "]";
	}

}
